﻿using System;

namespace LogikBug.Async
{
	/// <summary>
	/// Provides a base class and functionality for all disposable objects.
	/// </summary>
	public abstract class DisposableObject : IDisposable
	{
		#region Constructors

		~DisposableObject()
		{
			Dispose(false);
		}

		#endregion

		#region Properties

		///<summary>
		/// Determins if the current object is disposed.
		///</summary>
		public bool IsDisposed { get; private set; }

		///<summary>
		/// Determins if the current object is disposing.
		///</summary>
		public bool IsDisposing { get; private set; }

		#endregion

		#region Methods

		public virtual void Dispose()
		{
			if (AssertNotDisposedOrDisposing())
			{
				IsDisposing = true;
				
				Dispose(true);

				IsDisposing = false;
				IsDisposed = true;
			}
		}

		protected bool AssertNotDisposedOrDisposing()
		{
			if (!IsDisposed && !IsDisposing)
			{
				return true;
			}

			throw new ObjectDisposedException(GetType().FullName);
		}

		protected abstract void Dispose(bool disposing);

		#endregion
	}
}
